package zhongbo.java.air.ingestion.listen;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.stereotype.Component;
import zhongbo.java.air.ingestion.config.RedisListenerConfig;
import zhongbo.java.air.ingestion.dto.FlightPathDto;
import zhongbo.java.air.ingestion.model.AirFlightPath;
import zhongbo.java.air.ingestion.service.impl.AirIngestionServiceImpl;

import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

@Component
@Slf4j
//接收消息
public class RedisSubscribeLogChannelListener implements MessageListener {
    @Autowired
    private RedisLogChanelPublisher redisLogChanelPublisher;

    @Autowired
    private AirIngestionServiceImpl airIngestionService;

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public void onMessage(Message message, byte[] bytes) {
        String channel = new String(message.getChannel());
        String body = new String(message.getBody());
//        if ("flight_path_chanel".equals(channel)) {
            log.info("\n从频道：'{}'接收航迹原始数据消息 : {}", channel, body);

            if (channel.equals("injest_flight_path_tujiapeng")) {
                log.info("频道：{} 接收到消息",channel);
            }

//        System.out.println("\nsout打印 '" + channel + "': " + body);

            // 转换为AirFlightPathDto对象并发送到injest_flight_path频道
            FlightPathDto airFlightPathDto = convertToAirFlightPath(body);
            if (airFlightPathDto != null) {
                log.info("\n映射后的航迹数据: {}", airFlightPathDto); // 打印映射后的内容
                airIngestionService.publishInDB(airFlightPathDto); // 存入数据库
                String jsonMessage = convertToAirFlightPathJson(airFlightPathDto);
                System.out.println("\n转换后的JSON消息: " + jsonMessage); // 打印转换后的JSON消息到控制台
//                redisLogChanelPublisher.publish(RedisListenerConfig.INJEST_FLIGHT_PATH, jsonMessage); // 发送到injest_flight_path频道
                redisLogChanelPublisher.publish(RedisListenerConfig.LIVE_FLIGHT_PATH,jsonMessage);
            }
//        }
    }

    private FlightPathDto convertToAirFlightPath(String body) {
        if (body == null || body.isEmpty()) {
            log.error("消息为空");
            return null;
        }

        try {
            JSONObject jsonObject = JSONUtil.parseObj(body);
            FlightPathDto dto = new FlightPathDto();

            // 1. 解析基础字段
//            dto.setId(jsonObject.getStr("id")); // 原始数据未见id
            dto.setId(UUID.randomUUID().toString()); // 生成随机uuid (但如果是始终追踪一架飞机，那么id应该始终相同)
            dto.setIcao_code(jsonObject.getStr("icao")); // ICAO码

//            dto.setSource_type(jsonObject.getStr("type")); // 数据源类型(当type是字符串时)

            JSONObject jsonType = jsonObject.getJSONObject("type"); // 数据源类型(当type是json对象时)
            dto.setSource_type(jsonType.getStr("type"));

            // 2. 解析 trace 数组中的关键字段
            JSONArray traceArray = jsonObject.getJSONArray("trace");
            if (traceArray != null && traceArray.size() >= 6) { // 确保至少有6个元素
                // 直接提取 trace 中特定索引的值
                dto.setLatitude(traceArray.getDouble(1));     // trace[1]: 纬度
                dto.setLongitude(traceArray.getDouble(2));    // trace[2]: 经度
                dto.setAltitude(traceArray.getDouble(3));     // trace[3]: 高度
                dto.setSpeed(traceArray.getDouble(4));        // trace[4]: 速度
                dto.setHeading(traceArray.getDouble(5));      // trace[5]: 航向
            } else {
                log.warn("trace 数组缺失或长度不足");
            }

            // 4. 计算时间戳（timestamp + trace[0]）
            System.out.println("traceArray   - " + traceArray);
            if (jsonObject.containsKey("timestamp") && traceArray != null && traceArray.size() > 0) {
                Double timestamp = jsonObject.getDouble("timestamp"); // （UTC 时间）
                Double trace0 = traceArray.getDouble(0); // 毫秒级偏移量
                if (timestamp != null && trace0 != null) {
                    dto.setTimestamp(new Date((long) ((timestamp * 1000 + trace0))));
                }
            }

            return dto;
        } catch (Exception e) {
            log.error("转换消息失败: {}", body, e);
            return null;
        }
    }
    private String convertToAirFlightPathJson(FlightPathDto airFlightPathDto) {
        try {
            return objectMapper.writeValueAsString(airFlightPathDto);// writeValueAsString 将 Java 对象序列化为 JSON 字符串的方法
        } catch (IOException e) {
            log.error("转换为JSON字符串失败: {}", airFlightPathDto, e);
            return null;
        }
    }
}

